package info.batcloud.fanli.core.service.impl;

import com.ctospace.archit.common.pagination.Paging;
import com.taobao.api.ApiException;
import com.taobao.api.TaobaoClient;
import com.taobao.api.domain.ItemCat;
import com.taobao.api.request.ItemcatsGetRequest;
import com.taobao.api.response.ItemcatsGetResponse;
import info.batcloud.fanli.core.constants.CacheNameConstants;
import info.batcloud.fanli.core.constants.TaobaoClientConstants;
import info.batcloud.fanli.core.entity.TaobaoItemCat;
import info.batcloud.fanli.core.helper.PagingHelper;
import info.batcloud.fanli.core.repository.TaobaoItemCatRepository;
import info.batcloud.fanli.core.service.TaobaoItemCatService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import java.util.List;

@Service
@CacheConfig(cacheNames = CacheNameConstants.TAOBAO_ITEM_CAT)
public class TaobaoItemCatServiceImpl implements TaobaoItemCatService {

    private static final Logger logger = LoggerFactory.getLogger(TaobaoItemCatService.class);

    @Inject
    @Qualifier(TaobaoClientConstants.TAOBAO_CLIENT_ITEM_MANAGEMENT)
    private TaobaoClient taobaoClient;

    @Inject
    private TaobaoItemCatRepository taobaoItemCatRepository;


    @Override
    public void syncFromTaobao() {
        ItemcatsGetRequest req = new ItemcatsGetRequest();
        req.setParentCid(0l);
        try {
            ItemcatsGetResponse rsp = taobaoClient.execute(req);
            if (rsp.getItemCats() == null) {
                return;
            }
            for (ItemCat itemCat : rsp.getItemCats()) {
                TaobaoItemCat taobaoItemCat = new TaobaoItemCat();
                taobaoItemCat.setCid(itemCat.getCid());
                taobaoItemCat.setName(itemCat.getName());
                taobaoItemCat.setParentCid(itemCat.getParentCid());
                taobaoItemCat.setStatus(itemCat.getStatus());
                taobaoItemCat.setRelationName(itemCat.getName() + "@");
                taobaoItemCat.setRelationPath(itemCat.getCid() + "/");
                taobaoItemCat.setParent(itemCat.getIsParent());
                taobaoItemCatRepository.save(taobaoItemCat);
                this.syncChildren(taobaoItemCat);
            }
        } catch (ApiException e) {
            logger.error("同步淘宝类目出错", e);
        }

    }

    public void syncChildren(TaobaoItemCat parent) {
        ItemcatsGetRequest req = new ItemcatsGetRequest();
        req.setParentCid(parent.getCid());
        try {
            ItemcatsGetResponse rsp = taobaoClient.execute(req);
            if (rsp.getItemCats() == null) {
                return;
            }
            for (ItemCat itemCat : rsp.getItemCats()) {
                TaobaoItemCat taobaoItemCat = new TaobaoItemCat();
                taobaoItemCat.setCid(itemCat.getCid());
                taobaoItemCat.setName(itemCat.getName());
                taobaoItemCat.setParentCid(itemCat.getParentCid());
                taobaoItemCat.setStatus(itemCat.getStatus());
                taobaoItemCat.setRelationName(parent.getRelationName() + itemCat.getName() + "@");
                taobaoItemCat.setRelationPath(parent.getRelationPath() + itemCat.getCid() + "/");
                taobaoItemCat.setParent(itemCat.getIsParent());
                taobaoItemCatRepository.save(taobaoItemCat);
                if (itemCat.getIsParent()) {
                    this.syncChildren(taobaoItemCat);
                }
            }
        } catch (ApiException e) {
            logger.error("同步淘宝类目出错", e);
        }
    }

    @Override
    @Cacheable(key = "#name")
    public TaobaoItemCat findByName(String name, long parentCid) {
        return taobaoItemCatRepository.findByNameAndParentCid(name, parentCid);
    }

    @Override
    public Paging<TaobaoItemCat> search(SearchParam findParam) {
        Specification<TaobaoItemCat> specification = (root, query, cb) -> {
            Predicate predicate = cb.conjunction();
            List<Expression<Boolean>> expressions = predicate.getExpressions();
            if (findParam.getParentCid() != null) {
                if(findParam.getParentCid() == 0) {
                    expressions.add(cb.equal(root.get("parentCid"), findParam.getParentCid()));
                } else {
                    TaobaoItemCat taobaoItemCat = taobaoItemCatRepository.findOne(findParam.getParentCid());
                    expressions.add(cb.like(root.get("relationPath"), taobaoItemCat.getRelationPath() + "%"));
                }
            }
            if(StringUtils.isNotBlank(findParam.getRelationPath())) {
                expressions.add(cb.like(root.get("relationPath"), findParam.getRelationPath() + "%"));
            }
            if(findParam.getCid() != null) {
                expressions.add(cb.equal(root.get("cid"), findParam.getCid()));
            }
            if (StringUtils.isNotBlank(findParam.getName())) {
                expressions.add(cb.like(root.get("name"), "%" + findParam.getName() + "%"));
            }
            return predicate;
        };
        Pageable pageable = new PageRequest(findParam.getPage() - 1,
                findParam.getPageSize(), new Sort(Sort.Direction.ASC,"relationPath"));
        Page<TaobaoItemCat> page = taobaoItemCatRepository.findAll(specification, pageable);
        return PagingHelper .of(page, findParam.getPage(), findParam.getPageSize());
    }
}
